#include <memory>

#include "topconn_processor.hpp"

#include "topconn_cfg.hpp"
#include "topconn_cfg_loader.hpp"
#include "topconn_cfg_parser.hpp"
#include "topconn_exception.hpp"
#include "topconn_executor.hpp"
#include "topconn_logutil.hpp"

namespace topconn
{
	int ConnProcessor::sendPack(const string& connectorId, const string& connPath, const string& request, string& response,const string& atx)
	{
		char sError[256] = { 0 };

		TLOG_DEBUG("Request data=[%s]", request.c_str());

		TLOG_INFO("ConnectorId=%s",connectorId.c_str());
		TLOG_INFO("ConnectorPath=%s",connPath.c_str());

		RootCfg cfg;
		ConnResourceLoader::getConnCfg(connPath, cfg);
		if (cfg.getDocument().empty())
		{
			sprintf(sError,"The configuration definition is incorrect,Please check!!");
			TLOG_ERROR(sError);
			throw ConnException(sError);
		}
		TLOG_TRACE("The communication connection resource profile was loaded succed.");

		if (cfg.getRoot().empty())
		{
			sprintf(sError, "The configuration definition is incorrect, there is no root node, please check!!");
			TLOG_ERROR(sError);
			throw ConnException(sError);
		}

		auto root = cfg.getRoot();
		ConnConfigParser::parseRootCfg(root, cfg);
		return ConnProcessor::sendPack(connectorId, cfg, request, response,atx);
	}

	int ConnProcessor::sendPack(const string& connectorId, RootCfg& rootcfg, const string& request, string& response,const string& atx)
	{
		char sError[256] = { 0 };
		auto node = rootcfg.getRoot();

		pugi::xml_node connector_node = node.find_child_by_attribute("connector","id",connectorId.c_str());
		if (connector_node.empty())
		{
			sprintf(sError,"The specified configuration node [%s] information was not found.", connectorId.c_str());
			TLOG_ERROR(sError);
			throw ConnException(sError);
		}
		TLOG_TRACE("Get the communication node [%s] information succed.", connectorId.c_str());

		ProtocalCfg pc;
		ConnConfigParser::parseElementAttributes(connector_node, pc);
		string policyType = pc.get("type");
		if (policyType.empty())
		{
			sprintf(sError, "The communication node [%s] protocol type is empty", connectorId.c_str());
			TLOG_ERROR(sError);
			throw ConnException(sError);
		}
		TLOG_INFO("The communication protocol type = %s", policyType.c_str());

		pc.setType(policyType);
		pc.setElement(connector_node);
		Executor executor(policyType);
		return executor.sendPack(pc, policyType,request, response,atx);
	}

	int ConnProcessor::sendPack(const string& protocalType, map_t& params, const string& request, string& response,const string& atx)
	{
		ProtocalCfg pc(params);
		TLOG_INFO("The communication protocol type =%s", protocalType.c_str());

		pc.setType(protocalType);
		Executor executor(protocalType);
		return executor.sendPack(pc, protocalType, request, response, atx);
	}
};